音视频开发9. 使用ffmpeg 将pcm转码mp3实践(C++)

您所在的位置:网站首页 ffmpeg音频采集 51声道 音视频开发9. 使用ffmpeg 将pcm转码mp3实践(C++)

音视频开发9. 使用ffmpeg 将pcm转码mp3实践(C++)

2024-07-11 07:39| 来源: 网络整理| 查看: 265

@[TOC](音视频开发9. 使用ffmpeg 将pcm转码mp3实践(C++))

一、准备环境 CentOS环境安装 ffmpeg 库,并有必要的库(主要是lame:mp3解码库)ffmpeg库安装可参考之前文档 二、一些预备知识 1. 音频格式说明

如前文所述,pcm是音频裸数据,要转成mp3需要进行重采样、编码步骤。常见的PCM格式有8位和16位两种。

8位每一个PCM数据的值由一个字节即8位来表示(0-255)16位是指每一个PCM数据的值由两个字节即16位来表示,分为高8位和第8位(-32767~32767) 2. 采样频率

采样频率指每秒钟对音频的采样点数,单位为Hz(赫兹)。 如采样频率为44100hz是指每秒钟采集44100个样本点。

3. 声道数

常见的声道数有:

单声道:mono双声道:stereo,包含左右两声道2.1声道:在双声道基础上增加了一个低音声道5.1声道:分别为正面、左前方、右前方、左环绕、右环绕声道、一个低音声道7.1声道:在5.1声道的基础上,把左右的环绕声道拆分为左右环绕声道以及左右后置声道,主要应用于BD以及现代的电影院 4. 样本大小

例:

1024个16位单声道PCM样本,它的样本大小为102421=2048字节;1024个16位双声道PCM样本,它的样本大小为102422=4096字节 5. 一帧样本数 PCM 一般为1024;MP3 一般为 1152。 6. 参考命令行 ffmpeg -y -ac 1 -ar 16000 -f s16le -i /data/ffmpeg/test/input.pcm -c:a libmp3lame -q:a 2 /data/ffmpeg/test/output.mp3 三、几个重要函数 1. 重采样参数设置两个函数 3.1.1 swr_alloc_set_opts

示例:

SwrContext* swrContext = NULL; // 设置参数, 1. 重采样上下文 2.输出声道布局 4.输出采样率, 5.输入声道布局 6.输入样本格式 7.输入采样率 8.配音 9.日志 swrContext = swr_alloc_set_opts(swrContext, avCodecContext->channel_layout, avCodecContext->sample_fmt, avCodecContext->sample_rate, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100, 0, 0); 3.1.2 av_opt_set_int

示例:

SwrContext *swrContext = swr_alloc(); // 通道布局:立体声 av_opt_set_int(swrContext, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); // 采样率:44100 av_opt_set_int(swrContext, "in_sample_rate", OSR, 0); // 样本格式 s16交错存储 av_opt_set_sample_fmt(swrContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);

在设置完参数后,要调用swr_init进行初始化。

2. 分配样本数据内存空间 3.2.1 av_samples_alloc_array_and_samples

根据音频格式分配相应大小的内存空间,函数内部会调用 av_samples_alloc ,示例代码:

result = av_samples_alloc_array_and_samples(&input_data, &input_linesize, 2, avFrame->nb_samples, AV_SAMPLE_FMT_S16, 0); 3.2.2 av_samples_alloc

根据音频格式分配相应大小的内存空间。用于转换过程中对输出内存大小进行调整。

3. 整体流程

在这里插入图片描述

四、实现代码 1. CMakeLists.txt cmake_minimum_required(VERSION 3.17) project(ffmpeg_demo) # 设置ffmpeg依赖库及头文件所在目录,并存进指定变量 set(ffmpeg_libs_DIR /home/xundh/ffmpeg_sources/ffmpeg-4.2.2) set(ffmpeg_headers_DIR /home/xundh/ffmpeg_sources/ffmpeg-4.2.2) #对于find_package找不到的外部依赖库,可以用add_library添加 # SHARED表示添加的是动态库 # IMPORTED表示是引入已经存在的动态库 add_library( avcodec SHARED IMPORTED) add_library( avfilter SHARED IMPORTED ) add_library( swresample SHARED IMPORTED ) add_library( swscale SHARED IMPORTED ) add_library( avformat SHARED IMPORTED ) add_library( avutil SHARED IMPORTED ) #指定所添加依赖库的导入路径 set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavcodec/libavcodec.so ) set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavfilter/libavfilter.so ) set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswresample/libswresample.so ) set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswscale/libswscale.so ) set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavformat/libavformat.so ) set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavutil/libavutil.so ) # 添加头文件路径到编译器的头文件搜索路径下,多个路径以空格分隔 include_directories( ${ffmpeg_headers_DIR} ) link_directories(${ffmpeg_libs_DIR} ) link_directories(/usr/lib) set(CMAKE_CXX_STANDARD 14) # add_executable(ffmpeg_demo main.cpp) add_executable(ffmpeg_demo pcm_to_mp3.cpp) target_link_libraries(${PROJECT_NAME} avcodec avformat avutil swresample swscale swscale avfilter ) 2. 主文件 #include #ifdef __cplusplus extern "C" { #endif #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/imgutils.h" #include "libavutil/log.h" #include "libswresample/swresample.h" #include "libavutil/avutil.h" #include "libavutil/opt.h" #ifdef __cplusplus } #endif using namespace std; #define CHANNEL 2 #define OSR 44100 /** * pcm 转 mp3格式,输入文件路径 */ int pcm_to_mp3(const char *pcm_file_path, const char *mp3_file_path) { FILE *pcm_file = NULL; FILE *mp3_file = NULL; int result; // 获取mp3编码器 cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3